package cn.com.surker.interceptor;

import cn.com.surker.common.AESCoder;
import cn.com.surker.common.AbstractController;
import cn.com.surker.common.Constant;
import cn.com.surker.common.CookiesUtil;
import cn.com.surker.enums.StateEnum;
import cn.com.surker.enums.system.StationEnum;
import cn.com.surker.oauth.AuthUtils;
import cn.com.surker.redis.RedisUtils;
import cn.com.surker.system.entity.SysStationLog;
import cn.com.surker.system.entity.SysUser;
import cn.com.surker.system.model.CacheUser;
import cn.com.surker.system.service.*;
import cn.com.surker.util.IpUtils;
import cn.com.surker.util.StringUtils;
import cn.com.surker.wechat.WechatOaGroupApi;
import cn.com.surker.wechat.WechatSurkerGroupApi;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author lucky
 * @create 2021年02月22 15:01
 * @desc
 */
@Slf4j
@Component
public class ConfigInterceptor implements HandlerInterceptor {

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private DataSourceService dataSourceService;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private OriginService originService;
    @Resource
    private StationLogService logService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        if (request.getSession().getAttribute("oauth_token") != null)
            return true;

        Map<String, String> heads = new HashMap<String, String>();
        Enumeration<String> headNames = request.getHeaderNames();
        while (headNames.hasMoreElements()) {
            String name = headNames.nextElement();
            heads.put(name.toLowerCase(), request.getHeader(name));
        }
        String oauthType = request.getParameter("oauthType");
        if (!StringUtils.isNull(oauthType)) {//确认是否是单点登录
            String username = request.getParameter("username");
            String times = request.getParameter("timestamp");
            String echostr = request.getParameter("echostr");
            String oauthToken = request.getParameter("oauthToken");
            if (!StringUtils.isNull(username) && !StringUtils.isNull(times) && !StringUtils.isNull(echostr)
                    && !StringUtils.isNull(oauthToken)) {
                Long timestamp = StringUtils.convertLong(times);
                if ((new Date().getTime() - timestamp) / 1000 < 84400) {//有效期在十分钟内
                    echostr = echostr.replace(" ", "+");
                    String tempEcho = AESCoder.encrypt(oauthType + "_" + username + "_" + times, Constant.centerSecret);
                    if (echostr.equals(tempEcho)) {//比对加密参数是否正确
                        /**加密令牌**/
                        String appToken = AESCoder.decrypt(oauthToken, Constant.CACHE_USER);
                        if (StringUtils.isNull(appToken))
                            return false;

                        if (redisUtils.exists(appToken)) {
                            CacheUser cacheUser = (CacheUser) redisUtils.get(appToken);
                            appToken = AuthUtils.createToken(cacheUser.getId() + timestamp);
                            cacheUser.setToken(appToken);
                            AbstractController.setUserCookie(cacheUser);
                            return true;

                        }

                        SysUser user = userService.queryUser(username);
                        if (user != null) {
                            CacheUser cacheUser = new CacheUser(user);
                            cacheUser.setRoleList(roleService.loadUserMenu(user.getId()));
                            cacheUser.setRoleNameList(roleService.loadRoleName(cacheUser.getId()));
                            cacheUser.setIp(IpUtils.getIpAddress(request));
                            cacheUser = logService.save(cacheUser);
                            /**加密令牌**/
                            appToken = AuthUtils.createToken(cacheUser.getId() + timestamp);
                            cacheUser.setToken(appToken);
                            redisUtils.set(appToken, cacheUser, 7200L);

                            AbstractController.setUserCookie(cacheUser);
                            return true;
                        }
                    }
                }
            }
        }
        /**cookie缓存KEY**/
        String secretKey = Constant.COOKIE_KEY;

        /**每次进入时判断session是否为空，为空则根据本地cookies登录**/
        String token = CookiesUtil.getCookies(request, secretKey);
        /**判断cookies中的值是否不为空**/
        if (!StringUtils.isNull(token)) {
            if (!StringUtils.isNull(AESCoder.decrypt(token, secretKey))) {
                /**如果token不为空则解析cookie信息**/
                JSONObject jsonObject = JSONObject.parseObject(AESCoder.decrypt(token, secretKey));
                if (!StringUtils.isNull(jsonObject.getString("token"))) {
                    /**如果缓存用户存在**/
                    String cacheToken = jsonObject.getString("token");
                    if (redisUtils.exists(cacheToken)) {
                        CacheUser cacheUser = (CacheUser) redisUtils.get(cacheToken);
                        cacheUser.setRoleList(roleService.loadUserMenu(cacheUser.getId()));
                        cacheUser.setRoleNameList(roleService.loadRoleName(cacheUser.getId()));
                        if (StringUtils.isNull(cacheUser.getOriginId())) {
                            SysStationLog lastLog = logService.findByUid(cacheUser.getId(), StateEnum.ENABLED.getCode());
                            if (lastLog == null) {
                                cacheUser = logService.save(cacheUser);
                                AbstractController.setUserCookie(cacheUser);
                                return true;
                            }

                            /**加密令牌**/
                            String appToken = AuthUtils.createToken(cacheUser.getId() + new Date().getTime());
                            cacheUser.setToken(appToken);
                            redisUtils.set(appToken, cacheUser, 7200L);
                            cacheUser.setOriginName(lastLog.getOrgName());
                            cacheUser.setOriginId(lastLog.getOrgId());

                            /**新增登录记录**/
                            cacheUser = originService.choseStation(appToken, lastLog.getOrgId(),
                                    cacheUser.getId(), StationEnum.MIXING.getCode(), IpUtils.getIpAddress(request));
                        }

                        AbstractController.setUserCookie(cacheUser);
                        return true;
                    }
                }

                if (!StringUtils.isNull(jsonObject.getString("username"))
                        && !StringUtils.isNull(jsonObject.getString("password"))) {
                    SysUser sysUser = new SysUser();
                    sysUser.setUsername(jsonObject.getString("username"));
                    sysUser.setPassword(jsonObject.getString("password"));
                    sysUser.setStatus(StateEnum.ENABLED.getCode());

                    /**如果数据库中账号信息和cookies值能匹配则自动登录**/
                    SysUser user = userService.queryUser(sysUser.getUsername());
                    if (user != null && user.getPassword().equals(sysUser.getPassword())) {
                        CacheUser cacheUser = new CacheUser(user);
                        cacheUser.setRoleList(roleService.loadUserMenu(user.getId()));
                        cacheUser.setRoleNameList(roleService.loadRoleName(cacheUser.getId()));
                        SysStationLog lastLog = logService.findByUid(cacheUser.getId(), StateEnum.ENABLED.getCode());
                        AbstractController.setUserCookie(cacheUser);
                        if (lastLog == null) {
                            cacheUser = logService.save(cacheUser);
                            AbstractController.setUserCookie(cacheUser);
                            return true;
                        }

                        /**加密令牌**/
                        String appToken = AuthUtils.createToken(cacheUser.getId() + new Date().getTime());
                        cacheUser.setToken(appToken);
                        cacheUser.setOriginName(lastLog.getOrgName());
                        cacheUser.setOriginId(lastLog.getOrgId());

                        redisUtils.set(appToken, cacheUser, 7200L);
                        /**新增登录记录**/
                        cacheUser = originService.choseStation(appToken, lastLog.getOrgId(),
                                cacheUser.getId(), StationEnum.MIXING.getCode(), IpUtils.getIpAddress(request));
                        AbstractController.setUserCookie(cacheUser);
                        return true;
                    }
                } else {
                    CookiesUtil.removeCookies(secretKey, response);
                }
            }
        }

//        String appletToken = request.getParameter("appToken");
//        if (!StringUtils.isNull(appletToken)) {
//            if (redisUtils.exists(appletToken)) {
//                CacheUser cacheUser = (CacheUser) redisUtils.get(appletToken);
//                AbstractController.setUserCookie(cacheUser);
//                return true;
//            }
//        }

        if (uri.indexOf("/cloud/index") != -1 || uri.indexOf("/console/index") != -1
                || uri.indexOf("/cloud/flow-view") != -1 || uri.indexOf("/cloud/material/add") != -1
                || uri.indexOf("/cloud/seal/add") != -1 || uri.indexOf("/cloud/production/add") != -1
                || uri.indexOf("/cloud/expenses/add") != -1 || uri.indexOf("/cloud/borrow/add") != -1
                || uri.indexOf("/cloud/clock/in/record/detail") != -1|| uri.indexOf("/cloud/material/confirm") != -1) {
            if (request.getSession().getAttribute("oauth_token") == null) {
                /**企业微信授权登录码**/
                String code = request.getParameter("code");
                log.error("企业微信授权登录码:{}", code);
                if (StringUtils.isNull(code)) {
                    if (heads.get("user-agent").contains("wxwork")) {
                        CookiesUtil.removeCookies(secretKey, response);
                        log.error("企业微信客户端则重定向的OAuth验证链接;CorpID:{},web:{}" + WechatOaGroupApi.corpID, request.getServerName());
                        String rectUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                                + WechatOaGroupApi.corpID + "&redirect_uri=http://" + request.getServerName() + uri +
                                "?response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
                        log.error("rectUrl:--------" + rectUrl);
                        response.sendRedirect(rectUrl);
                        return false;
                    } else {
						response.sendRedirect("/console/login");
                        return false;
                    }
                } else {
                    String username = WechatOaGroupApi.getUserId(code, WechatOaGroupApi.corpID, WechatOaGroupApi.corpSecret);
                    log.error("企业微信授权登录码:{},微信登录用户名:{}", code, username);
                    SysUser user = userService.queryUser(username);
                    if (user != null) {
                        CacheUser cacheUser = new CacheUser(user);
                        cacheUser.setRoleList(roleService.loadUserMenu(user.getId()));
                        cacheUser.setRoleNameList(roleService.loadRoleName(cacheUser.getId()));
                        AbstractController.setUserCookie(cacheUser);
                        SysStationLog lastLog = logService.findByUid(cacheUser.getId(), StateEnum.ENABLED.getCode());
                        if (lastLog == null) {
                            cacheUser = logService.save(cacheUser);
                            AbstractController.setUserCookie(cacheUser);
                            return true;
                        }

                        /**加密令牌**/
                        String appToken = AuthUtils.createToken(cacheUser.getId() + new Date().getTime());
                        cacheUser.setToken(appToken);
                        redisUtils.set(appToken, cacheUser, 7200L);
                        cacheUser.setOriginName(lastLog.getOrgName());
                        cacheUser.setOriginId(lastLog.getOrgId());

                        /**新增登录记录**/
                        cacheUser = originService.choseStation(appToken, lastLog.getOrgId(),
                                cacheUser.getId(), StationEnum.MIXING.getCode(), IpUtils.getIpAddress(request));
                        AbstractController.setUserCookie(cacheUser);
                        return true;
                    }
                }
            }
        }

        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception ex) throws Exception {
    }

}
